package com.jichaoyun.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jichaoyun.common.enums.MyExceptiontType;
import com.jichaoyun.common.ex.MyException;
import com.jichaoyun.common.model.Result;
import com.jichaoyun.model.entity.Role;
import com.jichaoyun.model.entity.RoleMenu;
import com.jichaoyun.model.entity.User;
import com.jichaoyun.model.vo.RoleIdNameVo;
import com.jichaoyun.sys.mapper.RoleMapper;
import com.jichaoyun.sys.mapper.RoleMenuMapper;
import com.jichaoyun.sys.mapper.UserMapper;
import com.jichaoyun.sys.service.IRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhangzhen
 * @since 2023-11-03
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserMapper userMapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    /**
     * 新增角色
     * @param role
     * @return
     */
    @Override
    @Transactional
    public Result<Object> addRole(Role role) {

        String rolename = role.getRoleName();
        if(rolename == null){
            throw new MyException(MyExceptiontType.NOROLENAME,"角色名为空");
        }
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleName,rolename);
        Role result = this.baseMapper.selectOne(wrapper);

        if (result != null) {
            throw new MyException(MyExceptiontType.ROLEEXIEST,"角色已存在");
        }
//写入角色表
//        Integer roleid = role.getRoleId();
        roleMapper.insert(role);

//       写入角色菜单关系表
        if( null != role.getMenuIdList()){
            for (Integer menuId : role.getMenuIdList()) {
                roleMenuMapper.insert(new RoleMenu(null,role.getRoleId(),menuId));
            }
        }
        return Result.success("创建成功");
    }

    /**
     * 更新角色状态
     * @param roleId
     * @return
     */
    @Override
    public Result<Object> updateStatus(Integer roleId) {

        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getRoleId,roleId);
        Role result = this.baseMapper.selectOne(wrapper);

        if(result.getStatus().equals(true)){
            result.setStatus(false);
        } else if (result.getStatus().equals(false)) {
            result.setStatus(true);
        }
        roleMapper.updateById(result);
        return Result.success("修改成功");
    }

    /**
     * 查询所有角色Id和名称
     * @return
     */
    @Override
    public List<RoleIdNameVo> getAllRoleIdName() {
        List<RoleIdNameVo> resList = new ArrayList<>();
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status",1)
                .orderByAsc("role_id");
        List<Role> roleList = this.baseMapper.selectList(queryWrapper);
        for(Role role : roleList){
            RoleIdNameVo roleIdName = new RoleIdNameVo();
            roleIdName.setRoleId(role.getRoleId());
            roleIdName.setRoleName(role.getRoleName());
            roleIdName.setDescription(role.getRoleDescription());
            resList.add(roleIdName);
        }
        return resList;
    }

    /**
     * 获取角色列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public IPage<Role> getRoleList(Long pageNo, Long pageSize) {

        IPage<Role> roleIPage = new Page<>(pageNo,pageSize);
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("role_id");
        return roleMapper.selectPage(roleIPage,queryWrapper);
    }

    /**
     * 获取角色列表
     * @return
     */
    @Override
    public List<Role> getRoleList() {
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("role_id");
        return roleMapper.selectList(queryWrapper);
    }

    /**
     * 获取该角色的用户数量
     * @param roleId
     * @return
     */
    @Override
    public int getRoleNum(Integer roleId) {
        QueryWrapper<User> userQueryWrapper =  new QueryWrapper<User>();
        userQueryWrapper.eq("user_role",roleId);
        int count = (int) userMapper.selectCount(userQueryWrapper).longValue();
        return count;
    }

    /**
     * 根据Id获取角色
     * @param roleId
     * @return
     */
    @Override
    public Role getRoleById(Integer roleId) {
        Role role = this.baseMapper.selectById(roleId);
        List<Integer> menuIdList = roleMenuMapper.getMenuIdListByRoleId(roleId);
        role.setMenuIdList(menuIdList);
        return role;

    }

    /**
     * 修改角色信息及权限
     * @param role
     */
    @Override
    @Transactional
    public void updateRole(Role role) {
        if(!role.getRoleName().isEmpty()){
            LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Role::getRoleName,role.getRoleName());
            Role res = this.baseMapper.selectOne(lambdaQueryWrapper);
            if( res != null && !Objects.equals(res.getRoleId(), role.getRoleId()) ){
                throw new MyException(MyExceptiontType.DUPLICATEROLENAME,null);
            }
        }else {
            throw new MyException(MyExceptiontType.NOROLENAME,"角色名为空");
        }

        // 修改角色表
        this.baseMapper.updateById(role);
        // 删除原有权限
        LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenu::getRoleId,role.getRoleId());
        roleMenuMapper.delete(wrapper);
        // 新增权限
        if( null != role.getMenuIdList()){
            for (Integer menuId : role.getMenuIdList()) {
                roleMenuMapper.insert(new RoleMenu(null,role.getRoleId(),menuId));
            }
        }
    }

    /**
     * 删除角色及其对应权限
     * @param id
     */
    @Override
    public void deleteRoleById(Integer id) {
        this.baseMapper.deleteById(id);
        // 删除权限
        LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenu::getRoleId,id);
        roleMenuMapper.delete(wrapper);

        // 将用户表中与删除的角色关联的用户的 userRole 字段置为0
        LambdaQueryWrapper<User> userRoleWrapper = new LambdaQueryWrapper<>();
        userRoleWrapper.eq(User::getUserRole, id);
        List<User> userRoles = userMapper.selectList(userRoleWrapper);

        for (User userRole : userRoles) {
            // 修改用户表中的 userRole 字段为0
            userRole.setUserRole(0);
            this.userMapper.updateById(userRole);
        }
    }
}
